package com.jeesite.modules.wx.service.serviceImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeesite.modules.common.refun.CollectionUtil;
import com.jeesite.modules.common.refun.StringUtil;
import com.jeesite.modules.config.redis.RedisHandle;
import com.jeesite.modules.wx.entity.*;
import com.jeesite.modules.wx.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {

    @Autowired
    private WxUserDisValueRecordService wxUserDisValueRecordService;
    @Autowired
    private WxActivityService wxActivityService;
    @Autowired
    private WxUserService wxUserService;
    @Autowired
    private WxActivityDisUserService wxActivityDisUserService;
    @Autowired
    private WxUserActivityAfterService wxUserActivityAfterService;
    @Autowired
    private RefunService refunService;
    @Autowired
    private WxBusinessUserService wxBusinessUserService;
    @Autowired
    private WxBusinessUserTongjiService wxBusinessUserTongjiService;
    @Autowired
    private WxBusinessGroupService wxBusinessGroupService;
    @Autowired
    private RedisHandle redisHandle;

    @Override
    public Integer saveOrder(String activityId, String openId, String times, HttpServletRequest request, HttpServletResponse response) {

        WxUser wxUser = wxUserService.findByOpenId(openId);

        //查询活动的最新价格
        WxActivity wxActivity = wxActivityService.get(activityId);
        String price = wxActivity.getPrice();
        log.info("得到活动的价格={}",price);

        //查询获的返佣金
        String disValue = wxActivity.getDisValue();
        BigDecimal disValueBigDec = BigDecimal.ZERO;
        log.info("获得活动配置ide佣金={}",disValue);
        if(StringUtils.isNotEmpty(disValue)){
            try {
                disValueBigDec = new BigDecimal(disValue);

            }catch (Exception e){
                e.printStackTrace();

                log.error("获得活动的返佣价格错误={}",disValue);
            }

        }
        log.info("查询活动的返佣={}",disValueBigDec.toString());

        Boolean isInvite = false;
        String inviteUserOpenId = "";

        //查询openid用户之前保存的无效订单数据，用户对应的活动无效数据唯一，不会多条
        WxUserDisValueRecord findOrderByOpenIdAndActivityId = new WxUserDisValueRecord();
        findOrderByOpenIdAndActivityId.setBuyUserOpenId(openId);
        findOrderByOpenIdAndActivityId.setBuyActivityId(Long.valueOf(activityId));
        //查询用户购买活动的无效状态
        findOrderByOpenIdAndActivityId.setBuyFlag(0);
        List<WxUserDisValueRecord> wxUserDisValueRecordList = wxUserDisValueRecordService.findList(findOrderByOpenIdAndActivityId);
        log.info("回调后的saveOrder查询wxUserDisValueRecord={}",wxUserDisValueRecordList);
        if(CollectionUtils.isNotEmpty(wxUserDisValueRecordList)){
            WxUserDisValueRecord temp = wxUserDisValueRecordList.get(0);
            log.info("支付后查询wxuserdisvaluerecord temp={}",temp);
            //修改订单无效状态
            temp.setBuyFlag(1);
            //修改活动价格
            temp.setBuyPrice(new BigDecimal(price));
            //活动返佣价格
            temp.setDisMoneyValue(disValueBigDec);

            if(StringUtils.isNotEmpty(temp.getUserOpenId())){
                isInvite = true;
                inviteUserOpenId = temp.getUserOpenId();
            }

            log.info("回调更新数据 price={}",temp.getBuyPrice());
            log.info("回调更新数据 disMoneyValue={}",temp.getDisMoneyValue());
            wxUserDisValueRecordService.update(temp);
        }

        /**
         * 排除自己返佣自己的
         */
        if(openId.equals(inviteUserOpenId)){
            log.info("自己返佣自己了，跳过");
            isInvite = false;
        }
        log.info("是否返佣判断={}",isInvite);

        /**
         * 返佣开始
         */
        if(isInvite){
            /**
             * 推荐用户没有购买不给返佣
             */
            WxUserDisValueRecord checkInviteUserPay = new WxUserDisValueRecord();
            checkInviteUserPay.setBuyUserOpenId(inviteUserOpenId);
            checkInviteUserPay.setBuyActivityId(Long.valueOf(activityId));
            checkInviteUserPay.setBuyFlag(1);
            List<WxUserDisValueRecord> checkInviteRecordList = wxUserDisValueRecordService.findList(checkInviteUserPay);
            log.info("检查推荐用户是否购买过={}",checkInviteRecordList.size());
            if(CollectionUtil.isNotEmpty(checkInviteRecordList)){

                /**
                 * 员工推广购买++
                 */
                this.businessUserPayCount(wxActivity,openId,inviteUserOpenId);

                log.info("推荐用户购买过");
                try {
                    WxUser inviteWxUser = wxUserService.findByOpenId(inviteUserOpenId);

                    //商户号转账给微信用户
                    log.info("商家转钱给用户={}",inviteWxUser.getNickName());
                    log.info("商家转钱给用户佣金={}",disValue);

                    Integer paymoneyint = new BigDecimal(disValue).multiply(new BigDecimal(100)).intValue();
                    String payMoney=paymoneyint.toString();

                    Boolean refrun = refunService.transferPay(request,response,inviteUserOpenId,payMoney);
                    log.info("转账的结果={}",refrun);

                    if(refrun){
                        //修改用户表中的返佣
                        String oldMoney = inviteWxUser.getDisMoneyValue();
                        log.info("用户账户的旧返佣={}",oldMoney);
                        //旧返佣decimal转换类型
                        BigDecimal oldMoneyDec = BigDecimal.ZERO;
                        if (StringUtils.isNotEmpty(oldMoney)){
                            oldMoneyDec = new BigDecimal(oldMoney);
                        }
                        log.info("用户账户增加的返佣={}",disValueBigDec.toString());
                        //增加返佣金额
                        BigDecimal newMoneyDec = oldMoneyDec.add(disValueBigDec);
                        inviteWxUser.setDisMoneyValue(newMoneyDec.toString());
                        log.info("用户账户最终的返佣={}",newMoneyDec.toString());
                        wxUserService.update(inviteWxUser);

                        /**
                         * 更新红包缓存list
                         */
                        this.updateMoneyCacheList(activityId,inviteWxUser,disValue);

                        //增加wx_activity_dis_user记录，代表改活动下改用户有返佣金额操作，坐等收钱就可以
                        WxActivityDisUser wxActivityDisUser = new WxActivityDisUser();
                        wxActivityDisUser.setActivityId(activityId);
                        wxActivityDisUser.setUserOpenId(inviteUserOpenId);
                        //查询wxActivity表中
                        List<WxActivityDisUser> wxActivityDisUserList = wxActivityDisUserService.findList(wxActivityDisUser);
                        if(CollectionUtils.isNotEmpty(wxActivityDisUserList)){
                            log.info("有记录不操作了");
                        }else{
                            //增加一个userId
                            wxActivityDisUser.setUserId(Long.valueOf(inviteWxUser.getId()));
                            wxActivityDisUserService.insert(wxActivityDisUser);
                        }

                    }

                }catch (Exception e){
                    e.getMessage();
                    log.error("返佣失败={}",e.getMessage());
                }

            }else{

                log.info("=====邀请用户没有购买过商品，不执行返佣金====");
            }


        }

        /**
         * 用于我的订单功能，购买活动后对应的商家
         * 存在购买多次活动（现在不存在，只购买一次）
         */
        this.saveOrder(wxActivity,wxUser,times);

        return 1;
    }


    /**
     * 购买后保存订单
     * @param wxActivity
     * @param wxUser
     */
    public void saveOrder(WxActivity wxActivity,WxUser wxUser,String times){
        //查询活动绑定的商家分组
        Long groupId = wxActivity.getBusinessGroupId();
        //根据分组id查询分组中绑定的商家
        WxBusinessGroup wxBusinessGroup = new WxBusinessGroup();
        wxBusinessGroup.setConfigGroupId(groupId);
        List<WxBusinessGroup> wxBusinessGroupList = wxBusinessGroupService.findList(wxBusinessGroup);
        if(CollectionUtil.isNotEmpty(wxBusinessGroupList)){
            WxBusinessGroup findBusinessGroup = wxBusinessGroupList.get(0);
            //获得分组的商家ids
            String businessIds = findBusinessGroup.getBusinessIds();
            if(StringUtil.isNotEmpty(businessIds)){
                //分割字符串数据
                String[] businessIdsArray = businessIds.split(",");
                log.info("获取活动商家的id={}", Arrays.toString(businessIdsArray));
                int len = businessIdsArray.length;
                for(int i = 0; i< len; i++){
                    //保存我的订单，获取活动中的busines所有商家，插入到表中
                    WxUserActivityAfter wxUserActivityAfter = new WxUserActivityAfter();
                    //订单号
                    wxUserActivityAfter.setOrderNum(wxActivity.getId()+times);
                    wxUserActivityAfter.setActivityId(wxActivity.getId());
                    wxUserActivityAfter.setBusinessId(businessIdsArray[i]);
                    wxUserActivityAfter.setUserOpenId(wxUser.getWxOpenId());
                    wxUserActivityAfter.setUserId(wxUser.getId());
                    wxUserActivityAfterService.insert(wxUserActivityAfter);
                }
            }
        }
    }

    /**
     * 员工购买统计++
     */
    public void businessUserPayCount(WxActivity wxActivity,String openId,String inviteUserOpenId){
        if(StringUtil.isNotEmpty(inviteUserOpenId)){
            if(!inviteUserOpenId.equals(openId)){
                WxUser findInviteUser = wxUserService.findByOpenId(inviteUserOpenId);
                if(null != findInviteUser){
                    //查找他是否是员工
                    WxBusinessUser wxBusinessUser = new WxBusinessUser();
                    wxBusinessUser.setUserId(Long.valueOf(findInviteUser.getId()));
                    List<WxBusinessUser> wxBusinessUserList = wxBusinessUserService.findList(wxBusinessUser);
                    if(CollectionUtil.isEmpty(wxBusinessUserList)){
                        log.info("inviteOpenId不是员工");
                    }else{
                        //查看商家是否在活动当中
                        WxBusinessUser checkWxBusinesseUser = wxBusinessUserList.get(0);
                        Long businessId = checkWxBusinesseUser.getBusinessId();
                        String activityBusiness = wxActivity.getBusiness();
                        String activityBusinessApply = wxActivity.getBusinessApply();
                        if(StringUtil.isNotEmpty(activityBusiness)){
                            if(activityBusiness.contains(businessId.toString()) || activityBusinessApply.contains(businessId.toString())){

                                //员工统计
                                WxBusinessUserTongji wxBusinessUserTongji = new WxBusinessUserTongji();
                                //活动
                                wxBusinessUserTongji.setActivityId(Long.valueOf(wxActivity.getId()));
                                //员工的openId
                                wxBusinessUserTongji.setUserOpenId(inviteUserOpenId);
                                List<WxBusinessUserTongji> wxBusinessUserTongjiList = wxBusinessUserTongjiService.findList(wxBusinessUserTongji);
                                if(CollectionUtil.isNotEmpty(wxBusinessUserTongjiList)){
                                    WxBusinessUserTongji temp =  wxBusinessUserTongjiList.get(0);
                                    Long goumaiCount = temp.getGoumai();
                                    if(null == goumaiCount){
                                        goumaiCount = 0L;
                                    }
                                    temp.setGoumai(goumaiCount+1L);
                                    wxBusinessUserTongjiService.save(temp);
                                }else{
                                    //员工的userId
                                    wxBusinessUserTongji.setUserId(Long.valueOf(findInviteUser.getId()));
                                    wxBusinessUserTongji.setGoumai(1L);
                                    wxBusinessUserTongji.setWxBusinessUserId(Long.valueOf(wxBusinessUserList.get(0).getId()));
                                    wxBusinessUserTongjiService.save(wxBusinessUserTongji);
                                }

                            }else{
                                log.info("商家不在这次活动中，员工购买量++无效");
                            }
                        }
                    }
                }else{
                    log.info("检查购买量++员工用户未找到");
                }

            }else{
                log.info("自己购买自己了");
            }
        }

    }


    /**
     * 返佣后主动更新红包缓存list
     */
    public void updateMoneyCacheList(String activityId,WxUser inviteWxUser,String disValue){

        try {
            JSONArray cacheMoneyListArray = (JSONArray) redisHandle.get("moneyList:"+activityId);
            if(null != cacheMoneyListArray){
                int len = cacheMoneyListArray.size();
                Boolean flag = true;
                for(int i = 0; i < len;i++){
                    JSONObject jsonObject = (JSONObject) cacheMoneyListArray.get(i);
                    String cacheUserId = (String) jsonObject.get("userId");
                    if(cacheUserId.equals(inviteWxUser.getId())){
                        log.info("在缓存中找到了这个返佣用户，开始更新缓存计算");
                        String cacheDisMoney = (String) jsonObject.get("disMoney");
                        BigDecimal newDisCacheValue =
                                new BigDecimal(cacheDisMoney).add(new BigDecimal(disValue));
                        log.info("计算出更新用户={}的缓存红包金额={}",inviteWxUser.getWxOpenId(),newDisCacheValue.toString());
                        //更新json
                        jsonObject.put("disMoney",newDisCacheValue.toString());
                        //跳出去
                        flag = false;
                        //更新缓存排序
                        break;
                    }

                }
                //不在缓存中，主动添加上,排序
                if(flag){
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("userHeadImg",inviteWxUser.getHeadImg());
                    jsonObject.put("userName",inviteWxUser.getNickName());
                    //总反佣金
                    jsonObject.put("disMoney",new BigDecimal(inviteWxUser.getDisMoneyValue()).toString());
                    //总次数,
                    String disNum = inviteWxUser.getDisInviteNum();
                    if(StringUtil.isEmpty(disNum)){
                        disNum = "0";
                    }
                    jsonObject.put("disNum",disNum);
                    //userId
                    jsonObject.put("userId",inviteWxUser.getId());
                    cacheMoneyListArray.add(jsonObject);

                }

                //更新排序
                cacheMoneyListArray = updateSortCacheList(cacheMoneyListArray);
                //更新缓存，时间长度5小时
                redisHandle.set("moneyList:"+activityId,cacheMoneyListArray,60*60*5L);
            }
        }catch (Exception e){
            e.printStackTrace();
            //不要影响返佣
            log.error("返佣中更新红包缓存出错了={}",e.getMessage());
        }

    }

    /**
     * 排序array,array的size大于60位后面截取
     * @param jsonArray
     */
    public JSONArray updateSortCacheList(JSONArray jsonArray){
        //倒叙排列
        jsonArray.sort(Comparator.comparing(obj -> ((JSONObject) obj).getBigDecimal("disMoney")).reversed());
        //超过60截取
        int len = jsonArray.size();
        if(len > 60){
            List<Object> list = jsonArray.subList(0,59);
            JSONArray array= JSONArray.parseArray(JSON.toJSONString(list));
            log.info("array的size大于60位后面截取获得array={}",array);
            //赋值
            jsonArray = array;
        }

        return jsonArray;
    }


}
